package com.algorithms.arrays;

import com.algorithms.utils.AlgorithmException;

@SuppressWarnings("unchecked")
public class Array<T> {
	final int MAX_ELEMENT_COUNT = 10000;
	
	public T[] elements;
	
	private int maxArrayLength = MAX_ELEMENT_COUNT;
	private int arrayLength = 0;
	
	public Array(){
		elements = (T[]) new Object[MAX_ELEMENT_COUNT];
		maxArrayLength = MAX_ELEMENT_COUNT;
		arrayLength = 0;
	}
	
	public Array(int maxSizeOfArray){
		elements = (T[]) new Object[maxSizeOfArray];
		maxArrayLength = maxSizeOfArray;
		arrayLength = 0;
	}
	
	public boolean insert(int pos, T element) throws AlgorithmException {
		if (arrayLength == maxArrayLength){
			throw new AlgorithmException("element number has reached the maximum allowed number.");
		}else{
			if (pos >= arrayLength || pos < 0){
				throw new AlgorithmException("position to insert is out of range.");
			}else{
				if (pos < arrayLength - 1){
					for (int i = arrayLength - 1; i >= pos; i--){
						elements[i + 1] = elements[i];
					}
				}
				elements[pos] = element;
				arrayLength++;
				return true;
			}
		}
		
	}
	
	public boolean add(T element) throws AlgorithmException{
		if (arrayLength >= maxArrayLength){
			throw new AlgorithmException("number of elements is exceeded the maximum designed.");
		}else{
			elements[arrayLength] = element;
			arrayLength++;
			return true;
		}
	}
	
	public boolean remove(int pos) throws AlgorithmException{
		if (pos < 0 || pos >= arrayLength){
			throw new AlgorithmException("position to remove is out of range.");
		}else{
			if (pos < arrayLength - 1)
			for (int i = pos; i < arrayLength - 1; i++){
				elements[i] = elements[i + 1];
			}
			
			elements[arrayLength - 1] = null;
			arrayLength--;
			return true;
		}
	}
	
	public int size(){
		return arrayLength;
	}
	
	public void printElements(){
		for (int i = 0; i < arrayLength; i++){
			System.out.println(elements[i].toString());
		}
	}
}
